home *** CD-ROM | disk | FTP | other *** search
Wrap
package java.math; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.StreamCorruptedException; public class BigDecimal extends Number implements Comparable<BigDecimal> { private volatile BigInteger intVal; private int scale; private transient volatile int precision; private transient volatile String stringCache; private static final long INFLATED = Long.MIN_VALUE; private transient long intCompact; private static final int MAX_COMPACT_DIGITS = 18; private static final int MAX_BIGINT_BITS = 62; private static final long serialVersionUID = 6108874887143696463L; private static final BigDecimal[] zeroThroughTen; public static final BigDecimal ZERO; public static final BigDecimal ONE; public static final BigDecimal TEN; public static final int ROUND_UP = 0; public static final int ROUND_DOWN = 1; public static final int ROUND_CEILING = 2; public static final int ROUND_FLOOR = 3; public static final int ROUND_HALF_UP = 4; public static final int ROUND_HALF_DOWN = 5; public static final int ROUND_HALF_EVEN = 6; public static final int ROUND_UNNECESSARY = 7; private static BigInteger LONGMIN; private static BigInteger LONGMAX; private static BigInteger[] TENPOWERS; private static long[][] thresholds; private static int[] ilogTable; public BigDecimal(char[] var1, int var2, int var3) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; try { boolean var4 = false; if (var1[var2] == '-') { var4 = true; ++var2; --var3; } else if (var1[var2] == '+') { ++var2; --var3; } int var5 = -1; int var6 = var2; long var7 = 0L; if (var3 > var1.length) { throw new NumberFormatException(); } else { char[] var9; label152: for(var9 = new char[var3]; var3 > 0; --var3) { char var10 = var1[var2]; if ((var10 < '0' || var10 > '9') && !Character.isDigit(var10)) { if (var10 != '.') { if (var10 != 'e' && var10 != 'E') { throw new NumberFormatException(); } ++var2; var10 = var1[var2]; --var3; boolean var11 = false; if (var10 == '-' || var10 == '+') { var11 = var10 == '-'; ++var2; var10 = var1[var2]; --var3; } if (var3 <= 0) { throw new NumberFormatException(); } while(var3 > 10 && Character.digit(var10, 10) == 0) { ++var2; var10 = var1[var2]; --var3; } if (var3 > 10) { throw new NumberFormatException(); } while(true) { int var12; if (var10 >= '0' && var10 <= '9') { var12 = var10 - 48; } else { var12 = Character.digit(var10, 10); if (var12 < 0) { throw new NumberFormatException(); } } var7 = var7 * 10L + (long)var12; if (var3 == 1) { if (var11) { var7 = -var7; } if ((long)((int)var7) != var7) { throw new NumberFormatException(); } break label152; } ++var2; var10 = var1[var2]; --var3; } } if (var5 >= 0) { throw new NumberFormatException(); } var5 = var2; } else { var9[this.precision] = var10; ++this.precision; } ++var2; } if (this.precision == 0) { throw new NumberFormatException(); } else { if (var5 >= 0) { this.scale = this.precision - (var5 - var6); } if (var7 != 0L) { try { this.scale = this.checkScale(-var7 + (long)this.scale); } catch (ArithmeticException var13) { throw new NumberFormatException("Scale out of range."); } } int var19; for(var19 = 0; (var9[var19] == '0' || Character.digit(var9[var19], 10) == 0) && this.precision > 1; ++var19) { --this.precision; } char[] var20; if (!var4) { var20 = new char[this.precision]; System.arraycopy(var9, var19, var20, 0, this.precision); } else { var20 = new char[this.precision + 1]; var20[0] = '-'; System.arraycopy(var9, var19, var20, 1, this.precision); } if (this.precision <= 18) { this.intCompact = Long.parseLong(new String(var20)); } else { this.intVal = new BigInteger(var20); } } } } catch (ArrayIndexOutOfBoundsException var14) { throw new NumberFormatException(); } catch (NegativeArraySizeException var15) { throw new NumberFormatException(); } } public BigDecimal(char[] var1, int var2, int var3, MathContext var4) { this(var1, var2, var3); if (var4.precision > 0) { this.roundThis(var4); } } public BigDecimal(char[] var1) { this(var1, 0, var1.length); } public BigDecimal(char[] var1, MathContext var2) { this(var1, 0, var1.length, var2); } public BigDecimal(String var1) { this(var1.toCharArray(), 0, var1.length()); } public BigDecimal(String var1, MathContext var2) { this(var1.toCharArray(), 0, var1.length()); if (var2.precision > 0) { this.roundThis(var2); } } public BigDecimal(double var1) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; if (!Double.isInfinite(var1) && !Double.isNaN(var1)) { long var3 = Double.doubleToLongBits(var1); int var5 = var3 >> 63 == 0L ? 1 : -1; int var6 = (int)(var3 >> 52 & 2047L); long var7 = var6 == 0 ? (var3 & 4503599627370495L) << 1 : var3 & 4503599627370495L | 4503599627370496L; var6 -= 1075; if (var7 == 0L) { this.intVal = BigInteger.ZERO; this.intCompact = 0L; this.precision = 1; } else { while((var7 & 1L) == 0L) { var7 >>= 1; ++var6; } this.intVal = BigInteger.valueOf((long)var5 * var7); if (var6 < 0) { this.intVal = this.intVal.multiply(BigInteger.valueOf(5L).pow(-var6)); this.scale = -var6; } else if (var6 > 0) { this.intVal = this.intVal.multiply(BigInteger.valueOf(2L).pow(var6)); } if (this.intVal.bitLength() <= 62) { this.intCompact = this.intVal.longValue(); } } } else { throw new NumberFormatException("Infinite or NaN"); } } public BigDecimal(double var1, MathContext var3) { this(var1); if (var3.precision > 0) { this.roundThis(var3); } } public BigDecimal(BigInteger var1) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; this.intVal = var1; if (var1.bitLength() <= 62) { this.intCompact = var1.longValue(); } } public BigDecimal(BigInteger var1, MathContext var2) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; this.intVal = var1; if (var2.precision > 0) { this.roundThis(var2); } } public BigDecimal(BigInteger var1, int var2) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; this.intVal = var1; this.scale = var2; if (var1.bitLength() <= 62) { this.intCompact = var1.longValue(); } } public BigDecimal(BigInteger var1, int var2, MathContext var3) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; this.intVal = var1; this.scale = var2; if (var3.precision > 0) { this.roundThis(var3); } } public BigDecimal(int var1) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; this.intCompact = (long)var1; } public BigDecimal(int var1, MathContext var2) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; this.intCompact = (long)var1; if (var2.precision > 0) { this.roundThis(var2); } } public BigDecimal(long var1) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; if (compactLong(var1)) { this.intCompact = var1; } else { this.intVal = BigInteger.valueOf(var1); } } public BigDecimal(long var1, MathContext var3) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; if (compactLong(var1)) { this.intCompact = var1; } else { this.intVal = BigInteger.valueOf(var1); } if (var3.precision > 0) { this.roundThis(var3); } } private BigDecimal(long var1, int var3) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; this.intCompact = var1; this.scale = var3; } private BigDecimal(BigInteger var1, long var2, int var4) { this.scale = 0; this.precision = 0; this.stringCache = null; this.intCompact = Long.MIN_VALUE; this.intVal = var1; this.intCompact = var2; this.scale = var4; } public static BigDecimal valueOf(long var0, int var2) { if (var2 == 0 && var0 >= 0L && var0 <= 10L) { return zeroThroughTen[(int)var0]; } else { return compactLong(var0) ? new BigDecimal(var0, var2) : new BigDecimal(BigInteger.valueOf(var0), var2); } } public static BigDecimal valueOf(long var0) { return valueOf(var0, 0); } public static BigDecimal valueOf(double var0) { return new BigDecimal(Double.toString(var0)); } public BigDecimal add(BigDecimal var1) { BigDecimal[] var2 = new BigDecimal[]{this, var1}; matchScale(var2); long var3 = var2[0].intCompact; long var5 = var2[1].intCompact; if (var3 != Long.MIN_VALUE && var5 != Long.MIN_VALUE) { long var7 = var3 + var5; if (((var7 ^ var3) & (var7 ^ var5)) >> 63 == 0L) { return valueOf(var7, var2[0].scale); } } return new BigDecimal(var2[0].inflate().intVal.add(var2[1].inflate().intVal), var2[0].scale); } public BigDecimal add(BigDecimal var1, MathContext var2) { if (var2.precision == 0) { return this.add(var1); } else { BigDecimal var3 = this; this.inflate(); var1.inflate(); boolean var4 = this.signum() == 0; boolean var5 = var1.signum() == 0; if (!var4 && !var5) { long var10 = (long)this.scale - (long)var1.scale; if (var10 != 0L) { BigDecimal[] var11 = this.preAlign(this, var1, var10, var2); matchScale(var11); var3 = var11[0]; var1 = var11[1]; } return (new BigDecimal(var3.inflate().intVal.add(var1.inflate().intVal), var3.scale)).doRound(var2); } else { int var6 = Math.max(this.scale(), var1.scale()); if (var4 && var5) { return new BigDecimal(BigInteger.ZERO, 0L, var6); } else { BigDecimal var7 = var4 ? var1.doRound(var2) : this.doRound(var2); if (var7.scale() == var6) { return var7; } else if (var7.scale() > var6) { return (new BigDecimal(var7.intVal, var7.intCompact, var7.scale)).stripZerosToMatchScale((long)var6); } else { int var8 = var2.precision - var7.precision(); int var9 = var6 - var7.scale(); return var8 >= var9 ? var7.setScale(var6) : var7.setScale(var7.scale() + var8); } } } } } private BigDecimal[] preAlign(BigDecimal var1, BigDecimal var2, long var3, MathContext var5) { assert var3 != 0L; BigDecimal var6; BigDecimal var7; if (var3 < 0L) { var6 = var1; var7 = var2; } else { var6 = var2; var7 = var1; } long var8 = (long)var6.scale - (long)var6.precision() + (long)var5.precision; long var10 = (long)var7.scale - (long)var7.precision() + 1L; if (var10 > (long)(var6.scale + 2) && var10 > var8 + 2L) { var7 = valueOf((long)var7.signum(), this.checkScale(Math.max((long)var6.scale, var8) + 3L)); } BigDecimal[] var12 = new BigDecimal[]{var6, var7}; return var12; } public BigDecimal subtract(BigDecimal var1) { BigDecimal[] var2 = new BigDecimal[]{this, var1}; matchScale(var2); long var3 = var2[0].intCompact; long var5 = var2[1].intCompact; if (var3 != Long.MIN_VALUE && var5 != Long.MIN_VALUE) { long var7 = var3 - var5; if (((var3 ^ var5) & (var7 ^ var3)) >> 63 == 0L) { return valueOf(var7, var2[0].scale); } } return new BigDecimal(var2[0].inflate().intVal.subtract(var2[1].inflate().intVal), var2[0].scale); } public BigDecimal subtract(BigDecimal var1, MathContext var2) { if (var2.precision == 0) { return this.subtract(var1); } else { this.inflate(); var1.inflate(); BigDecimal var3 = new BigDecimal(var1.intVal.negate(), var1.scale); var3.precision = var1.precision; return this.add(var3, var2); } } public BigDecimal multiply(BigDecimal var1) { long var2 = this.intCompact; long var4 = var1.intCompact; int var6 = this.checkScale((long)this.scale + (long)var1.scale); if (var2 != Long.MIN_VALUE && var4 != Long.MIN_VALUE) { long var7 = var2 * var4; if (var4 == 0L || var7 / var4 == var2) { return valueOf(var7, var6); } } BigDecimal var9 = new BigDecimal(this.inflate().intVal.multiply(var1.inflate().intVal), var6); return var9; } public BigDecimal multiply(BigDecimal var1, MathContext var2) { return var2.precision == 0 ? this.multiply(var1) : this.inflate().multiply(var1.inflate()).doRound(var2); } public BigDecimal divide(BigDecimal var1, int var2, int var3) { if (var3 >= 0 && var3 <= 7) { BigDecimal var4; if (this.checkScale((long)var2 + (long)var1.scale) >= this.scale) { var4 = this.setScale(var2 + var1.scale); } else { var4 = this; var1 = var1.setScale(this.checkScale((long)this.scale - (long)var2)); } boolean var5 = var4.intCompact != Long.MIN_VALUE && var1.intCompact != Long.MIN_VALUE; long var6 = Long.MIN_VALUE; long var8 = Long.MIN_VALUE; BigInteger var10 = null; BigInteger var11 = null; if (var5) { var6 = var4.intCompact / var1.intCompact; var8 = var4.intCompact % var1.intCompact; } else { BigInteger[] var12 = var4.inflate().intVal.divideAndRemainder(var1.inflate().intVal); var10 = var12[0]; var11 = var12[1]; } if (var5) { if (var8 == 0L) { return new BigDecimal(var6, var2); } } else if (var11.signum() == 0) { return new BigDecimal(var10, var2); } if (var3 == 7) { throw new ArithmeticException("Rounding necessary"); } else { int var15 = var4.signum() * var1.signum(); boolean var13; if (var3 == 0) { var13 = true; } else if (var3 == 1) { var13 = false; } else if (var3 == 2) { var13 = var15 > 0; } else if (var3 == 3) { var13 = var15 < 0; } else { int var14; if (var5) { var14 = longCompareTo(Math.abs(2L * var8), Math.abs(var1.intCompact)); } else { var14 = var11.add(var11).abs().compareTo(var1.intVal.abs()); } if (var14 < 0) { var13 = false; } else if (var14 > 0) { var13 = true; } else if (var3 == 4) { var13 = true; } else if (var3 == 5) { var13 = false; } else if (var5) { var13 = (var6 & 1L) != 0L; } else { var13 = var10.testBit(0); } } if (var5) { if (var13) { var6 += (long)var15; } return new BigDecimal(var6, var2); } else { return var13 ? new BigDecimal(var10.add(BigInteger.valueOf((long)var15)), var2) : new BigDecimal(var10, var2); } } } else { throw new IllegalArgumentException("Invalid rounding mode"); } } public BigDecimal divide(BigDecimal var1, int var2, RoundingMode var3) { return this.divide(var1, var2, var3.oldMode); } public BigDecimal divide(BigDecimal var1, int var2) { return this.divide(var1, this.scale, var2); } public BigDecimal divide(BigDecimal var1, RoundingMode var2) { return this.divide(var1, this.scale, var2.oldMode); } public BigDecimal divide(BigDecimal var1) { if (var1.signum() == 0) { if (this.signum() == 0) { throw new ArithmeticException("Division undefined"); } else { throw new ArithmeticException("Division by zero"); } } else { int var2 = (int)Math.max(Math.min((long)this.scale() - (long)var1.scale(), 2147483647L), -2147483648L); if (this.signum() == 0) { return new BigDecimal(0L, var2); } else { this.inflate(); var1.inflate(); MathContext var3 = new MathContext((int)Math.min((long)this.precision() + (long)Math.ceil((double)10.0F * (double)var1.precision() / (double)3.0F), 2147483647L), RoundingMode.UNNECESSARY); BigDecimal var4; try { var4 = this.divide(var1, var3); } catch (ArithmeticException var6) { throw new ArithmeticException("Non-terminating decimal expansion; no exact representable decimal result."); } int var5 = var4.scale(); return var2 > var5 ? var4.setScale(var2) : var4; } } } public BigDecimal divide(BigDecimal var1, MathContext var2) { if (var2.precision == 0) { return this.divide(var1); } else { BigDecimal var3 = this.inflate(); BigDecimal var4 = var1.inflate(); long var6 = (long)var3.scale() - (long)var4.scale(); if (var4.signum() == 0) { if (var3.signum() == 0) { throw new ArithmeticException("Division undefined"); } else { throw new ArithmeticException("Division by zero"); } } else if (var3.signum() == 0) { return new BigDecimal(BigInteger.ZERO, (int)Math.max(Math.min(var6, 2147483647L), -2147483648L)); } else { BigDecimal var8 = new BigDecimal(var3.intVal.abs(), var3.precision()); BigDecimal var9 = new BigDecimal(var4.intVal.abs(), var4.precision()); if ((var2.roundingMode == RoundingMode.CEILING || var2.roundingMode == RoundingMode.FLOOR) && var8.signum() != var3.signum() ^ var9.signum() != var4.signum()) { var2 = new MathContext(var2.precision, var2.roundingMode == RoundingMode.CEILING ? RoundingMode.FLOOR : RoundingMode.CEILING); } if (var8.compareTo(var9) > 0) { --var9.scale; } BigDecimal var5 = var8.divide(var9, var2.precision, var2.roundingMode.oldMode); var5.scale = this.checkScale((long)var9.scale - (long)var8.scale - (long)(var4.scale - var3.scale) + (long)var2.precision); if (var3.signum() != var4.signum()) { var5 = var5.negate(); } var5 = var5.doRound(var2); return var5.multiply(var1).compareTo(this) == 0 ? var5.stripZerosToMatchScale(var6) : var5; } } } public BigDecimal divideToIntegralValue(BigDecimal var1) { int var2 = (int)Math.max(Math.min((long)this.scale() - (long)var1.scale(), 2147483647L), -2147483648L); this.inflate(); var1.inflate(); if (this.abs().compareTo(var1.abs()) < 0) { return valueOf(0L, var2); } else if (this.signum() == 0 && var1.signum() != 0) { return this.setScale(var2); } else { int var3 = (int)Math.min((long)this.precision() + (long)Math.ceil((double)10.0F * (double)var1.precision() / (double)3.0F) + Math.abs((long)this.scale() - (long)var1.scale()) + 2L, 2147483647L); BigDecimal var4 = this.divide(var1, new MathContext(var3, RoundingMode.DOWN)); if (var4.scale > 0) { var4 = var4.setScale(0, RoundingMode.DOWN).stripZerosToMatchScale((long)var2); } if (var4.scale < var2) { var4 = var4.setScale(var2); } return var4; } } public BigDecimal divideToIntegralValue(BigDecimal var1, MathContext var2) { if (var2.precision != 0 && this.abs().compareTo(var1.abs()) >= 0) { int var3 = (int)Math.max(Math.min((long)this.scale() - (long)var1.scale(), 2147483647L), -2147483648L); BigDecimal var4 = this.divide(var1, new MathContext(var2.precision, RoundingMode.DOWN)); int var5 = var4.scale(); if (var4.scale() < 0) { BigDecimal var6 = var4.multiply(var1); if (this.subtract(var6).abs().compareTo(var1.abs()) >= 0) { throw new ArithmeticException("Division impossible"); } } else if (var4.scale() > 0) { var4 = var4.setScale(0, RoundingMode.DOWN); } int var7; return var3 > var4.scale() && (var7 = var2.precision - var4.precision()) > 0 ? var4.setScale(var4.scale() + Math.min(var7, var3 - var4.scale)) : var4.stripZerosToMatchScale((long)var3); } else { return this.divideToIntegralValue(var1); } } public BigDecimal remainder(BigDecimal var1) { BigDecimal[] var2 = this.divideAndRemainder(var1); return var2[1]; } public BigDecimal remainder(BigDecimal var1, MathContext var2) { BigDecimal[] var3 = this.divideAndRemainder(var1, var2); return var3[1]; } public BigDecimal[] divideAndRemainder(BigDecimal var1) { BigDecimal[] var2 = new BigDecimal[]{this.divideToIntegralValue(var1), null}; var2[1] = this.subtract(var2[0].multiply(var1)); return var2; } public BigDecimal[] divideAndRemainder(BigDecimal var1, MathContext var2) { if (var2.precision == 0) { return this.divideAndRemainder(var1); } else { BigDecimal[] var3 = new BigDecimal[]{this.divideToIntegralValue(var1, var2), null}; var3[1] = this.subtract(var3[0].multiply(var1)); return var3; } } public BigDecimal pow(int var1) { if (var1 >= 0 && var1 <= 999999999) { int var2 = this.checkScale((long)this.scale * (long)var1); this.inflate(); return new BigDecimal(this.intVal.pow(var1), var2); } else { throw new ArithmeticException("Invalid operation"); } } public BigDecimal pow(int var1, MathContext var2) { if (var2.precision == 0) { return this.pow(var1); } else if (var1 >= -999999999 && var1 <= 999999999) { if (var1 == 0) { return ONE; } else { this.inflate(); BigDecimal var3 = this; MathContext var4 = var2; int var5 = Math.abs(var1); if (var2.precision > 0) { int var6 = this.intLength(var5); if (var6 > var2.precision) { throw new ArithmeticException("Invalid operation"); } var4 = new MathContext(var2.precision + var6 + 1, var2.roundingMode); } BigDecimal var9 = ONE; boolean var7 = false; int var8 = 1; while(true) { var5 += var5; if (var5 < 0) { var7 = true; var9 = var9.multiply(var3, var4); } if (var8 == 31) { if (var1 < 0) { var9 = ONE.divide(var9, var4); } return var9.doRound(var2); } if (var7) { var9 = var9.multiply(var9, var4); } ++var8; } } } else { throw new ArithmeticException("Invalid operation"); } } public BigDecimal abs() { return this.signum() < 0 ? this.negate() : this; } public BigDecimal abs(MathContext var1) { return this.signum() < 0 ? this.negate(var1) : this.plus(var1); } public BigDecimal negate() { BigDecimal var1; if (this.intCompact != Long.MIN_VALUE) { var1 = valueOf(-this.intCompact, this.scale); } else { var1 = new BigDecimal(this.intVal.negate(), this.scale); var1.precision = this.precision; } return var1; } public BigDecimal negate(MathContext var1) { return this.negate().plus(var1); } public BigDecimal plus() { return this; } public BigDecimal plus(MathContext var1) { return var1.precision == 0 ? this : this.doRound(var1); } public int signum() { return this.intCompact != Long.MIN_VALUE ? Long.signum(this.intCompact) : this.intVal.signum(); } public int scale() { return this.scale; } public int precision() { int var1 = this.precision; if (var1 == 0) { var1 = this.digitLength(); this.precision = var1; } return var1; } public BigInteger unscaledValue() { return this.inflate().intVal; } public BigDecimal round(MathContext var1) { return this.plus(var1); } public BigDecimal setScale(int var1, RoundingMode var2) { return this.setScale(var1, var2.oldMode); } public BigDecimal setScale(int var1, int var2) { if (var2 >= 0 && var2 <= 7) { if (var1 == this.scale) { return this; } else if (this.signum() == 0) { return valueOf(0L, var1); } else if (var1 > this.scale) { int var3 = this.checkScale((long)var1 - (long)this.scale); if (this.intCompact != Long.MIN_VALUE) { long var4 = longTenToThe(this.intCompact, var3); if (var4 != Long.MIN_VALUE) { return valueOf(var4, var1); } this.inflate(); } BigDecimal var6 = new BigDecimal(this.intVal.multiply(tenToThe(var3)), var1); if (this.precision > 0) { var6.precision = this.precision + var1 - this.scale; } return var6; } else { return this.divide(ONE, var1, var2); } } else { throw new IllegalArgumentException("Invalid rounding mode"); } } public BigDecimal setScale(int var1) { return this.setScale(var1, 7); } public BigDecimal movePointLeft(int var1) { int var2 = this.checkScale((long)this.scale + (long)var1); BigDecimal var3; if (this.intCompact != Long.MIN_VALUE) { var3 = valueOf(this.intCompact, var2); } else { var3 = new BigDecimal(this.intVal, var2); } return var3.scale < 0 ? var3.setScale(0) : var3; } public BigDecimal movePointRight(int var1) { int var2 = this.checkScale((long)this.scale - (long)var1); BigDecimal var3; if (this.intCompact != Long.MIN_VALUE) { var3 = valueOf(this.intCompact, var2); } else { var3 = new BigDecimal(this.intVal, var2); } return var3.scale < 0 ? var3.setScale(0) : var3; } public BigDecimal scaleByPowerOfTen(int var1) { this.inflate(); BigDecimal var2 = new BigDecimal(this.intVal, this.checkScale((long)this.scale - (long)var1)); var2.precision = this.precision; return var2; } public BigDecimal stripTrailingZeros() { this.inflate(); return (new BigDecimal(this.intVal, this.scale)).stripZerosToMatchScale(Long.MIN_VALUE); } public int compareTo(BigDecimal var1) { int var2 = this.signum() - var1.signum(); if (var2 != 0) { return var2 > 0 ? 1 : -1; } else { int var3 = this.precision() - this.scale; int var4 = var1.precision() - var1.scale; if (var3 < var4) { return -this.signum(); } else if (var3 > var4) { return this.signum(); } else { BigDecimal[] var5 = new BigDecimal[]{this, var1}; matchScale(var5); return var5[0].intCompact != Long.MIN_VALUE && var5[1].intCompact != Long.MIN_VALUE ? longCompareTo(var5[0].intCompact, var5[1].intCompact) : var5[0].inflate().intVal.compareTo(var5[1].inflate().intVal); } } } public boolean equals(Object var1) { if (!(var1 instanceof BigDecimal)) { return false; } else { BigDecimal var2 = (BigDecimal)var1; if (this.scale != var2.scale) { return false; } else if (this.intCompact != Long.MIN_VALUE && var2.intCompact != Long.MIN_VALUE) { return this.intCompact == var2.intCompact; } else { return this.inflate().intVal.equals(var2.inflate().intVal); } } } public BigDecimal min(BigDecimal var1) { return this.compareTo(var1) <= 0 ? this : var1; } public BigDecimal max(BigDecimal var1) { return this.compareTo(var1) >= 0 ? this : var1; } public int hashCode() { if (this.intCompact != Long.MIN_VALUE) { long var1 = this.intCompact < 0L ? -this.intCompact : this.intCompact; int var3 = (int)((long)((int)(var1 >>> 32) * 31) + (var1 & 4294967295L)); return 31 * (this.intCompact < 0L ? -var3 : var3) + this.scale; } else { return 31 * this.intVal.hashCode() + this.scale; } } public String toString() { if (this.stringCache == null) { this.stringCache = this.layoutChars(true); } return this.stringCache; } public String toEngineeringString() { return this.layoutChars(false); } public String toPlainString() { BigDecimal var1 = this; if (this.scale < 0) { var1 = this.setScale(0); } var1.inflate(); return var1.scale == 0 ? var1.intVal.toString() : var1.getValueString(var1.signum(), var1.intVal.abs().toString(), var1.scale); } private String getValueString(int var1, String var2, int var3) { int var5 = var2.length() - var3; if (var5 == 0) { return (var1 < 0 ? "-0." : "0.") + var2; } else { StringBuilder var4; if (var5 > 0) { var4 = new StringBuilder(var2); var4.insert(var5, '.'); if (var1 < 0) { var4.insert(0, '-'); } } else { var4 = new StringBuilder(3 - var5 + var2.length()); var4.append(var1 < 0 ? "-0." : "0."); for(int var6 = 0; var6 < -var5; ++var6) { var4.append('0'); } var4.append(var2); } return var4.toString(); } } public BigInteger toBigInteger() { return this.setScale(0, 1).inflate().intVal; } public BigInteger toBigIntegerExact() { return this.setScale(0, 7).inflate().intVal; } public long longValue() { return this.intCompact != Long.MIN_VALUE && this.scale == 0 ? this.intCompact : this.toBigInteger().longValue(); } public long longValueExact() { if (this.intCompact != Long.MIN_VALUE && this.scale == 0) { return this.intCompact; } else if (this.precision() - this.scale > 19) { throw new ArithmeticException("Overflow"); } else if (this.signum() == 0) { return 0L; } else if (this.precision() - this.scale <= 0) { throw new ArithmeticException("Rounding necessary"); } else { BigDecimal var1 = this.setScale(0, 7).inflate(); if (var1.precision() >= 19) { if (LONGMIN == null) { LONGMIN = BigInteger.valueOf(Long.MIN_VALUE); LONGMAX = BigInteger.valueOf(Long.MAX_VALUE); } if (var1.intVal.compareTo(LONGMIN) < 0 || var1.intVal.compareTo(LONGMAX) > 0) { throw new ArithmeticException("Overflow"); } } return var1.intVal.longValue(); } } public int intValue() { return this.intCompact != Long.MIN_VALUE && this.scale == 0 ? (int)this.intCompact : this.toBigInteger().intValue(); } public int intValueExact() { long var1 = this.longValueExact(); if ((long)((int)var1) != var1) { throw new ArithmeticException("Overflow"); } else { return (int)var1; } } public short shortValueExact() { long var1 = this.longValueExact(); if ((long)((short)((int)var1)) != var1) { throw new ArithmeticException("Overflow"); } else { return (short)((int)var1); } } public byte byteValueExact() { long var1 = this.longValueExact(); if ((long)((byte)((int)var1)) != var1) { throw new ArithmeticException("Overflow"); } else { return (byte)((int)var1); } } public float floatValue() { return this.scale == 0 && this.intCompact != Long.MIN_VALUE ? (float)this.intCompact : Float.parseFloat(this.toString()); } public double doubleValue() { return this.scale == 0 && this.intCompact != Long.MIN_VALUE ? (double)this.intCompact : Double.parseDouble(this.toString()); } public BigDecimal ulp() { return valueOf(1L, this.scale()); } private String layoutChars(boolean var1) { if (this.scale == 0) { return this.intCompact != Long.MIN_VALUE ? Long.toString(this.intCompact) : this.intVal.toString(); } else { char[] var2; if (this.intCompact != Long.MIN_VALUE) { var2 = Long.toString(Math.abs(this.intCompact)).toCharArray(); } else { var2 = this.intVal.abs().toString().toCharArray(); } StringBuilder var3 = new StringBuilder(var2.length + 14); if (this.signum() < 0) { var3.append('-'); } long var4 = -((long)this.scale) + (long)(var2.length - 1); if (this.scale >= 0 && var4 >= -6L) { int var9 = this.scale - var2.length; if (var9 >= 0) { var3.append('0'); var3.append('.'); while(var9 > 0) { var3.append('0'); --var9; } var3.append(var2); } else { var3.append(var2, 0, -var9); var3.append('.'); var3.append(var2, -var9, this.scale); } } else { if (var1) { var3.append(var2[0]); if (var2.length > 1) { var3.append('.'); var3.append(var2, 1, var2.length - 1); } } else { int var6 = (int)(var4 % 3L); if (var6 < 0) { var6 += 3; } var4 -= (long)var6; ++var6; if (this.signum() == 0) { switch (var6) { case 1: var3.append('0'); break; case 2: var3.append("0.00"); var4 += 3L; break; case 3: var3.append("0.0"); var4 += 3L; break; default: throw new AssertionError("Unexpected sig value " + var6); } } else if (var6 >= var2.length) { var3.append(var2, 0, var2.length); for(int var7 = var6 - var2.length; var7 > 0; --var7) { var3.append('0'); } } else { var3.append(var2, 0, var6); var3.append('.'); var3.append(var2, var6, var2.length - var6); } } if (var4 != 0L) { var3.append('E'); if (var4 > 0L) { var3.append('+'); } var3.append(var4); } } return var3.toString(); } } private static BigInteger tenToThe(int var0) { if (var0 < TENPOWERS.length) { return TENPOWERS[var0]; } else { char[] var1 = new char[var0 + 1]; var1[0] = '1'; for(int var2 = 1; var2 <= var0; ++var2) { var1[var2] = '0'; } return new BigInteger(var1); } } private static long longTenToThe(long var0, int var2) { return var2 >= 0 && var2 < thresholds.length && Math.abs(var0) <= thresholds[var2][0] ? var0 * thresholds[var2][1] : Long.MIN_VALUE; } private static boolean compactLong(long var0) { return var0 != Long.MIN_VALUE; } private BigDecimal inflate() { if (this.intVal == null) { this.intVal = BigInteger.valueOf(this.intCompact); } return this; } private static void matchScale(BigDecimal[] var0) { if (var0[0].scale < var0[1].scale) { var0[0] = var0[0].setScale(var0[1].scale); } else if (var0[1].scale < var0[0].scale) { var0[1] = var0[1].setScale(var0[0].scale); } } private synchronized void readObject(ObjectInputStream var1) throws IOException, ClassNotFoundException { var1.defaultReadObject(); if (this.intVal == null) { String var2 = "BigDecimal: null intVal in stream"; throw new StreamCorruptedException(var2); } else { this.intCompact = Long.MIN_VALUE; } } private void writeObject(ObjectOutputStream var1) throws IOException { this.inflate(); var1.defaultWriteObject(); } private int digitLength() { if (this.intCompact != Long.MIN_VALUE && Math.abs(this.intCompact) <= 2147483647L) { return this.intLength(Math.abs((int)this.intCompact)); } else if (this.signum() == 0) { return 1; } else { this.inflate(); BigInteger var1 = this.intVal; int var2 = 0; while(var1.mag.length > 1) { var1 = var1.divide(TENPOWERS[9]); var2 += 9; if (var1.signum() == 0) { return var2; } } var2 += this.intLength(var1.mag[0]); return var2; } } private int intLength(int var1) { if (var1 < 0) { return 10; } else if (var1 <= 9) { return 1; } else { int var3; for(var3 = -1; var1 > ilogTable[var3 + 1]; ++var3) { } return var3 + 1; } } private BigDecimal stripZerosToMatchScale(long var1) { boolean var3 = this.intCompact != Long.MIN_VALUE; this.inflate(); while(this.intVal.abs().compareTo(BigInteger.TEN) >= 0 && (long)this.scale > var1 && !this.intVal.testBit(0)) { BigInteger[] var4 = this.intVal.divideAndRemainder(BigInteger.TEN); if (var4[1].signum() != 0) { break; } this.intVal = var4[0]; this.scale = this.checkScale((long)this.scale - 1L); if (this.precision > 0) { --this.precision; } } if (var3) { this.intCompact = this.intVal.longValue(); } return this; } private int checkScale(long var1) { if ((long)((int)var1) != var1) { if ((this.intCompact == Long.MIN_VALUE || this.intCompact == 0L) && (this.intVal == null || this.signum() == 0) && (this.intVal != null || this.intCompact != Long.MIN_VALUE)) { return var1 > 2147483647L ? Integer.MAX_VALUE : Integer.MIN_VALUE; } if (var1 > 2147483647L) { throw new ArithmeticException("Underflow"); } if (var1 < -2147483648L) { throw new ArithmeticException("Overflow"); } } return (int)var1; } private BigDecimal roundOp(MathContext var1) { BigDecimal var2 = this.doRound(var1); return var2; } private void roundThis(MathContext var1) { BigDecimal var2 = this.doRound(var1); if (var2 != this) { this.intVal = var2.intVal; this.intCompact = var2.intCompact; this.scale = var2.scale; this.precision = var2.precision; } } private BigDecimal doRound(MathContext var1) { this.inflate(); if (this.precision == 0) { if (var1.roundingMax != null && this.intVal.compareTo(var1.roundingMax) < 0 && this.intVal.compareTo(var1.roundingMin) > 0) { return this; } this.precision(); } int var2 = this.precision - var1.precision; if (var2 <= 0) { return this; } else { BigDecimal var3 = this.dropDigits(var1, var2); return var3.doRound(var1); } } private BigDecimal dropDigits(MathContext var1, int var2) { BigDecimal var3 = new BigDecimal(tenToThe(var2), 0); BigDecimal var4 = this.divide(var3, this.scale, var1.roundingMode.oldMode); var4.scale = this.checkScale((long)var4.scale - (long)var2); return var4; } private static int longCompareTo(long var0, long var2) { return var0 < var2 ? -1 : (var0 == var2 ? 0 : 1); } private static void print(String var0, BigDecimal var1) { System.err.format("%s:\tintCompact %d\tintVal %d\tscale %d\tprecision %d%n", var0, var1.intCompact, var1.intVal, var1.scale, var1.precision); } private BigDecimal audit() { if (this.precision > 0 && this.precision != this.digitLength()) { print("audit", this); throw new AssertionError("precision mismatch"); } else { if (this.intCompact == Long.MIN_VALUE) { if (this.intVal == null) { print("audit", this); throw new AssertionError("null intVal"); } } else if (this.intVal != null) { long var1 = this.intVal.longValue(); if (var1 != this.intCompact) { print("audit", this); throw new AssertionError("Inconsistent state, intCompact=" + this.intCompact + "\t intVal=" + var1); } } return this; } } static { zeroThroughTen = new BigDecimal[]{new BigDecimal(BigInteger.ZERO, 0L, 0), new BigDecimal(BigInteger.ONE, 1L, 0), new BigDecimal(BigInteger.valueOf(2L), 2L, 0), new BigDecimal(BigInteger.valueOf(3L), 3L, 0), new BigDecimal(BigInteger.valueOf(4L), 4L, 0), new BigDecimal(BigInteger.valueOf(5L), 5L, 0), new BigDecimal(BigInteger.valueOf(6L), 6L, 0), new BigDecimal(BigInteger.valueOf(7L), 7L, 0), new BigDecimal(BigInteger.valueOf(8L), 8L, 0), new BigDecimal(BigInteger.valueOf(9L), 9L, 0), new BigDecimal(BigInteger.TEN, 10L, 0)}; ZERO = zeroThroughTen[0]; ONE = zeroThroughTen[1]; TEN = zeroThroughTen[10]; LONGMIN = null; LONGMAX = null; TENPOWERS = new BigInteger[]{BigInteger.ONE, BigInteger.valueOf(10L), BigInteger.valueOf(100L), BigInteger.valueOf(1000L), BigInteger.valueOf(10000L), BigInteger.valueOf(100000L), BigInteger.valueOf(1000000L), BigInteger.valueOf(10000000L), BigInteger.valueOf(100000000L), BigInteger.valueOf(1000000000L)}; thresholds = new long[][]{{Long.MAX_VALUE, 1L}, {922337203685477580L, 10L}, {92233720368547758L, 100L}, {9223372036854775L, 1000L}, {922337203685477L, 10000L}, {92233720368547L, 100000L}, {9223372036854L, 1000000L}, {922337203685L, 10000000L}, {92233720368L, 100000000L}, {9223372036L, 1000000000L}, {922337203L, 10000000000L}, {92233720L, 100000000000L}, {9223372L, 1000000000000L}, {92233L, 10000000000000L}}; ilogTable = new int[]{0, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE}; } }